package tech.waterism.utils.method;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tech.waterism.constant.DispatchConstants;
import tech.waterism.dto.*;
import tech.waterism.entity.DZqSpillway;
import tech.waterism.utils.CommonFun;
import tech.waterism.utils.ConvertZV;
import tech.waterism.utils.DecimalConvert;
import tech.waterism.utils.MathFun;

import java.util.List;

/**
 * 蓄滞洪区调洪
 */
@Component
public class StoreFlood {

    @Autowired
    private StoreFlow outFlow;

    public DispatchTempDataDto makePlanByGivenInflow(DispatchTempDataDto dispatchTempData, int indexObject,
                                                     List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                     int timeNum, int timeNumOperate, int diversionOrDischarge) {
        if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates() == null) {
            // 设置初始的口门开启个数
            Integer[][] nUsedGates = new Integer[topoObjects.get(indexObject).getFpIndex().getSpillways().size()][];
            for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
                int statusSize = topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates();
                nUsedGates[j] = new Integer[statusSize];
                for (int k = 0; k < statusSize; k++) {
                    nUsedGates[j][k] = 0;
                }
            }
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setNUsedGates(nUsedGates);
        }

        // 第0个时段不用计算, 只需将库容计算出来即可
        if (timeNum == timeNumOperate) {
            //            nPeriods = commonDatas.length;
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                    .setFlowWay(DispatchConstants.FLOW_WAY_DOUBLE_GATE_BY_RUNGEKUTTA);
            //			data.get(timeNum).gateNote = "";
            if (topoObjects.get(indexObject).getFpIndex().getCurveHs() != null) {
                CurveZVDto zvDto = ConvertZV.getVFromZ(topoObjects.get(indexObject).getFpIndex().getCurveHs(),
                        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getRz());
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setV(zvDto.getResult());
                ConvertZV.setErrMsgCurveHs(topoObjects.get(indexObject).getFpIndex(), zvDto.getMsg());
            }
        } else {
            dispatchTempData = makePlanByPrinciple(dispatchTempData, indexObject, topoObjects, principleData, timeNum,
                    timeNumOperate, diversionOrDischarge);
        }
        return dispatchTempData;
    }

    /**
     * 按调度规则检查方案
     */
    public DispatchTempDataDto checkPlanByGivenInflow(DispatchTempDataDto dispatchTempData, int indexObject,
                                                      List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                      int timeNum, int timeNumOperate) {
        // 第0个时段不用计算, 只需将库容计算出来即可
        if (timeNum > timeNumOperate) {
            dispatchTempData = checkPlanByPrinciple(dispatchTempData, indexObject, topoObjects, principleData, timeNum,
                    timeNumOperate);
        }
        return dispatchTempData;
    }

    /**
     * 根据闸门宽度编制调度方案（蓄滞洪区）
     */
    public DispatchTempDataDto makePlanbyGivenGateWidth(DispatchTempDataDto dispatchTempData, int indexObject,
                                                        List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                        int timeNum, int timeNumOperate, int diversionOrDischarge) {
        if (timeNum == timeNumOperate) {
            //            nPeriods = commonDatas.length;
            if (topoObjects.get(indexObject).getFpIndex().getCurveHs() != null) {
                CurveZVDto zvDto = ConvertZV.getVFromZ(topoObjects.get(indexObject).getFpIndex().getCurveHs(),
                        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getRz());
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setV(zvDto.getResult());
                ConvertZV.setErrMsgCurveHs(topoObjects.get(indexObject).getFpIndex(), zvDto.getMsg());
            }
        } else {
            // 记录界面传入的蓄滞洪区的参数
            //            record = (DS_ProcessRes) CommonFun.copyOneObject(data.get(timeNum));
            // 需要重新调度一遍, 将蓄滞洪区的入流改过来, 原来蓄滞洪区的入流为虚拟节点的入流, 同时计算虚拟节点的参数
            //            dispatchTempData = principleData.getFlowByPrinciple(dispatchTempData, indexObject,
            //            topoObjects, timeNum, timeNumOperate, diversionOrDischarge);
            int[] iGradeData = dispatchTempData.getIGradeData();
            //            data.get(timeNum) = (DS_ProcessRes) CommonFun.copyOneObject(record);
            // 分解flowWay, 若flowWay = 21, 则对应分后口门为固定宽度，排洪口门为调度规则
            // flowWay=22, 分后口门与排洪口门均为固定宽度
            int x = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getFlowWay();
            // 分解后, flowWays[0]对应排洪口, flowWays[1]对应分洪口
            int[] flowWays = new int[2];
            int num = 0;
            while (x >= 1) {
                flowWays[num] = x % 10;
                x = x / 10;
                num++;
            }
            //            temp = (principleData.getResNode(idComp + "1") != null)?principleData.getResNode(idComp +
            //            "1"):principleData.getResNode(idComp + "V");
            String mannerNote = "";

            if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DIVERSION) {
                if (flowWays[1] == 2) {
                    int gateWidthSim = 0;
                    for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
                        for (int k = 0;
                             k < topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates();
                             k++) {
                            // 分洪口
                            if (topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getSpillwaytype() ==
                                    1) {
                                // 修改后, 第一个口门宽度为修改的口门宽度, 后面都按照该宽度进行计算
                                //                                if (dispatchTempData.getIndexFen() > 0) {
                                //                                    topoObjects.get(indexObject).getFpIndex()
                                //                                    .getData().get(timeNum).getNUsedGates()[j][k] =
                                //                                    topoObjects.get(indexObject).getFpIndex()
                                //                                    .getData().get(timeNum - 1).getNUsedGates()[j][k];
                                //                                    // 这里的data.get(timeNum).qIn改成data.get(timeNum -
                                //                                    1).qIn 或者是对应组合入流流量
                                ////                                double zUp = MathFun.insert3(data.get(timeNum -
                                // 1).qIn, outflow.spillWay[j].zq[k].y,
                                ////                                        outflow.spillWay[j].zq[k].x, outflow
                                // .spillWay[j].zq[k].n);
                                //                                    double qUp = topoObjects.get(indexObject)
                                //                                    .getFpIndex().getData().get(timeNum).getQPrep();
                                //                                    if(principleData != null){
                                //                                        dispatchTempData = principleData.getQUp
                                //                                        (dispatchTempData, indexObject, timeNum,
                                //                                        topoObjects);
                                //                                        qUp = dispatchTempData.getQUp();
                                //                                    }
                                //                                    double zUp = MathFun.insert3(qUp,
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getSpillways().get(j).getZqMethods()
                                //                                            .get(k).getZqSpillways().stream()
                                //                                            .mapToDouble(DZqSpillway::getQ).toArray(),
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getSpillways().get(j).getZqMethods()
                                //                                            .get(k).getZqSpillways().stream()
                                //                                            .mapToDouble(DZqSpillway::getZ).toArray(),
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getSpillways().get(j).getZqMethods()
                                //                                            .get(k).getZqSpillways().size());
                                //                                    topoObjects.get(indexObject).getFpIndex()
                                //                                    .getData().get(timeNum).setQDvr(outFlow
                                //                                    .getOutFlow(
                                //                                            zUp,
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getData().get(timeNum - 1).getRz(),
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getSpillways(),
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getSpillways().get(j).getSpillwayid(),
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getData().get(timeNum).getNUsedGates
                                //                                            ()[j][k],
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getHsh0s()));
                                //                                } else {
                                if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                        .getNUsedGates()[j][k] > 0) {
                                    //                                        if (spillWayType == 1 || spillWayType
                                    //                                        == 3) {
                                    // 这里的data.get(timeNum).qIn改成data.get(timeNum - 1).qIn
                                    //                                        double zUp = MathFun.insert3(data.get
                                    //                                        (timeNum - 1).qIn,
                                    //                                                outflow.spillWay[j].zq[k].y,
                                    //                                                outflow.spillWay[j].zq[k].x,
                                    //                                                outflow.spillWay[j].zq[k].n);
                                    double qUp =
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep();
                                    if (principleData != null) {
                                        dispatchTempData = principleData
                                                .getQUp(dispatchTempData, indexObject, timeNum, topoObjects);
                                        qUp = dispatchTempData.getQUp();
                                    }
                                    double zUp = MathFun.insert3(qUp,
                                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                    .getZqMethods().get(k).getZqSpillways().stream()
                                                    .mapToDouble(DZqSpillway::getQ).toArray(),
                                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                    .getZqMethods().get(k).getZqSpillways().stream()
                                                    .mapToDouble(DZqSpillway::getZ).toArray(),
                                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                    .getZqMethods().get(k).getZqSpillways().size());
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(
                                            outFlow.getOutFlow(zUp,
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                            .getRz(),
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways(),
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                            .getSpillwayid(),
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                                            .getNUsedGates()[j][k],
                                                    topoObjects.get(indexObject).getFpIndex().getHsh0s()));
                                    //                                            dispatchTempData.setIndexFen(timeNum);
                                    //                                        } else {
                                    //										data.get(timeNum).qIn = qFenOrg;
                                    //										gateWidthSim = (int) (data.get(timeNum)
                                    //										.nUsedGates[j][k]
                                    //												* outflow.spillWay[j].gateWidth);
                                    //                                        }
                                } else {
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(0.0);
                                }
                                //                                }
                                gateWidthSim = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                        .getNUsedGates()[j][k];
                                mannerNote = mannerNote +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getShortname() +
                                        " " +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getStatename() + "-" + gateWidthSim + ";";
                            }
                        } // end for
                    }
                } else {
                    for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
                        for (int k = 0;
                             k < topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates();
                             k++) {
                            if (topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getSpillwayid() == 1) {
                                //                            double zUp = MathFun.insert3(data.get(timeNum - 1).qIn,
                                //                            outflow.spillWay[j].zq[k].y,
                                //                                    outflow.spillWay[j].zq[k].x, outflow
                                //                                    .spillWay[j].zq[k].n);
                                double zUp = MathFun.insert3(
                                        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().stream().mapToDouble(DZqSpillway::getQ)
                                                .toArray(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().stream().mapToDouble(DZqSpillway::getZ)
                                                .toArray(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().size());
                                double gateWidthSim = 0;
                                if (dispatchTempData.getIndexFen() > 0) {
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                            .getNUsedGates()[j][k] =
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                    .getNUsedGates()[j][k];
                                    // 按照宽的口门计算分洪流量
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(
                                            outFlow.getOutFlow(zUp,
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                            .getRz(),
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways(),
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                            .getSpillwayid(),
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                                            .getNUsedGates()[j][k],
                                                    topoObjects.get(indexObject).getFpIndex().getHsh0s()));
                                } else {
                                    // 判断是否修改的是分洪方式, 若修改的为分洪方式, 只要修改流量后,
                                    // 后面都按照该流量对应的口门宽度进行分洪
                                    //                                    if (spillWayType == 1 || spillWayType == 3) {
                                    // 根据入流计算口门宽
                                    gateWidthSim = outFlow.getGateWidth(zUp,
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                    .getRz(),
                                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                    .getSpillwayid(),
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDvr(),
                                            topoObjects.get(indexObject).getFpIndex().getSpillways(),
                                            topoObjects.get(indexObject).getFpIndex().getHsh0s());
                                    // 换算成口门数目
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                            .getNUsedGates()[j][k] = (int) gateWidthSim;
                                    dispatchTempData.setIndexFen(timeNum);
                                    //                                    } else {
                                    //									topoObjects.get(indexObject).getFpIndex()
                                    //									.getData().get(timeNum).qIn = qFenOrg;
                                    //									gateWidthSim = (int) (topoObjects.get
                                    //									(indexObject).getFpIndex().getData().get
                                    //									(timeNum).nUsedGates[j][k]
                                    //											* outflow.spillWay[j].gateWidth);
                                    //                                    }
                                }
                                gateWidthSim = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                        .getNUsedGates()[j][k];
                                mannerNote = mannerNote +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getShortname() +
                                        " " +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getStatename() + "-" + DecimalConvert.convert(gateWidthSim, 0) +
                                        ";";
                            }
                        }
                    } // end for
                }
            }

            if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DISCHARGE) {
                mannerNote = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getGateNote();
                if (flowWays[0] == 2) {
                    for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
                        for (int k = 0;
                             k < topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates();
                             k++) {
                            // 排洪口
                            if (topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getSpillwaytype() ==
                                    2) {
                                int gateWidthSim = 0;
                                //                                double qDsc = (topoObjects.get(indexObject)
                                //                                .getFpIndex().getData().get(timeNum - 1).getQDsc()
                                //                                != null)?topoObjects.get(indexObject).getFpIndex()
                                //                                .getData().get(timeNum - 1).getQDsc():0;
                                //                                double qDown = topoObjects.get(indexObject)
                                //                                .getFpIndex().getData().get(timeNum - 1).getQDown()
                                //                                + qDsc;
                                double qDown =
                                        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDown();
                                if (principleData != null) {
                                    dispatchTempData =
                                            principleData.getQDown(dispatchTempData, indexObject, timeNum, topoObjects);
                                    qDown = dispatchTempData.getQDown();
                                }
                                double zDown = MathFun.insert3(qDown,
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().stream().mapToDouble(DZqSpillway::getQ)
                                                .toArray(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().stream().mapToDouble(DZqSpillway::getZ)
                                                .toArray(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().size());
                                //                                if (dispatchTempData.getIndexPai() > 0) {
                                //                                    if (topoObjects.get(indexObject).getFpIndex()
                                //                                    .getData().get(timeNum)
                                //                                            .getNUsedGates()[j][k] <
                                //                                            topoObjects.get(indexObject).getFpIndex
                                //                                            ().getData().get(timeNum - 1)
                                //                                                    .getNUsedGates()[j][k]) {
                                //                                        topoObjects.get(indexObject).getFpIndex()
                                //                                        .getData().get(timeNum)
                                //                                                .getNUsedGates()[j][k] =
                                //                                                topoObjects.get(indexObject)
                                //                                                .getFpIndex().getData().get(timeNum
                                //                                                - 1)
                                //                                                        .getNUsedGates()[j][k];
                                //                                    }
                                //                                    topoObjects.get(indexObject).getFpIndex()
                                //                                    .getData().get(timeNum).setQDsc(
                                //                                            outFlow.getOutFlow(
                                //                                                    topoObjects.get(indexObject)
                                //                                                    .getFpIndex().getData().get
                                //                                                    (timeNum - 1)
                                //                                                            .getRz(), zDown,
                                //                                                    topoObjects.get(indexObject)
                                //                                                    .getFpIndex().getSpillways(),
                                //                                                    topoObjects.get(indexObject)
                                //                                                    .getFpIndex().getSpillways()
                                //                                                    .get(j)
                                //                                                            .getSpillwayid(),
                                //                                                    topoObjects.get(indexObject)
                                //                                                    .getFpIndex().getData().get
                                //                                                    (timeNum)
                                //                                                            .getNUsedGates()[j][k],
                                //                                                    topoObjects.get(indexObject)
                                //                                                    .getFpIndex().getHsh0s()));
                                //                                } else {
                                //                                    if (spillWayType == 2 || spillWayType == 3) {

                                if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                        .getNUsedGates()[j][k] > 0) {
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(
                                            outFlow.getOutFlow(
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                            .getRz(), zDown,
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways(),
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                            .getSpillwayid(),
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                                            .getNUsedGates()[j][k],
                                                    topoObjects.get(indexObject).getFpIndex().getHsh0s()));
                                    //                                        dispatchTempData.setIndexPai(timeNum);
                                } else {
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(0.0);
                                }
                                //                                    } else {
                                //									topoObjects.get(indexObject).getFpIndex()
                                //									.getData().get(timeNum).qOut = qPaiOrg;
                                //                                    }
                                //                                }
                                gateWidthSim = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                        .getNUsedGates()[j][k];
                                mannerNote = mannerNote +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getShortname() +
                                        " " +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getStatename() + "-" + gateWidthSim + ";";
                            }
                        } // end for
                    }
                } else {
                    for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
                        for (int k = 0;
                             k < topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates();
                             k++) {
                            if (topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getSpillwayid() == 2) {
                                double qDown = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                        .getQDown() +
                                        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1).getQDsc();
                                double zDown = MathFun.insert3(qDown,
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().stream().mapToDouble(DZqSpillway::getQ)
                                                .toArray(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().stream().mapToDouble(DZqSpillway::getZ)
                                                .toArray(),
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getZqSpillways().size());
                                double gateWidthSim = 0;
                                if (dispatchTempData.getIndexPai() > 0) {
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                            .getNUsedGates()[j][k] =
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                    .getNUsedGates()[j][k];
                                    gateWidthSim = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                            .getNUsedGates()[j][k];
                                    // 按照宽的口门计算分洪流量
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(
                                            outFlow.getOutFlow(
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                            .getRz(), zDown,
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways(),
                                                    topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                            .getSpillwayid(),
                                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                                            .getNUsedGates()[j][k],
                                                    topoObjects.get(indexObject).getFpIndex().getHsh0s()));
                                } else {
                                    //                                    if (spillWayType == 2 || spillWayType == 3) {
                                    gateWidthSim = outFlow.getGateWidth(
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1)
                                                    .getRz(), zDown,
                                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j)
                                                    .getSpillwayid(),
                                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDsc(),
                                            topoObjects.get(indexObject).getFpIndex().getSpillways(),
                                            topoObjects.get(indexObject).getFpIndex().getHsh0s());
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                                            .getNUsedGates()[j][k] = (int) gateWidthSim;
                                    // 根据口门数据重新计算口门宽
                                    //									gateWidthSim = topoObjects.get(indexObject)
                                    //									.getFpIndex().getData().get(timeNum)
                                    //									.nUsedGates[j][k]
                                    //											* outflow.spillWay[j].gateWidth;
                                    // 换算成口门数目
                                    //									topoObjects.get(indexObject).getFpIndex()
                                    //									.getData().get(timeNum).nUsedGates[j][k] =
                                    //									(int) Math
                                    //											.ceil(gateWidthSim / outflow
                                    //											.spillWay[j].gateWidth);
                                    dispatchTempData.setIndexPai(timeNum);
                                    //                                    } else {
                                    //									topoObjects.get(indexObject).getFpIndex()
                                    //									.getData().get(timeNum).qOut = qPaiOrg;
                                    //									gateWidthSim = (int) (topoObjects.get
                                    //									(indexObject).getFpIndex().getData().get
                                    //									(timeNum).nUsedGates[j][k]
                                    //											* outflow.spillWay[j].gateWidth);
                                    //                                    }
                                }
                                mannerNote = mannerNote +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getShortname() +
                                        " " +
                                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods()
                                                .get(k).getStatename() + "-" + DecimalConvert.convert(gateWidthSim, 0) +
                                        ";";
                            }
                        }
                    } // end for
                }
            }

            // 入流合理性校核
            if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDvr() >
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep()) {
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                        .setQDvr(topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep());
            }

            // 水量平衡计算,
            resRoutingOnePeriod(timeNum, topoObjects.get(indexObject));// 内部自动判断出流是否超过
            // 计算虚拟节点的出流
            //            temp.resPlans[0].common[timeNum].qOut = temp.resPlans[0].common[timeNum].qIn - data.get
            //            (timeNum).qIn + data.get(timeNum).qOut;
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote(mannerNote);
        }
        return dispatchTempData;
    }

    //spillWayType-1为分洪口门, 2为排洪口门, 3为两个口门同时修改, 0为不开闸
    public DispatchTempDataDto makePlanbyGivenGateNum(DispatchTempDataDto dispatchTempData, int indexObject,
                                                      List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                      int timeNum, int timeNumOperate, int diversionOrDischarge) {
        //        record = null;
        if (timeNum == timeNumOperate) {
            //            nPeriods = commonDatas.length;
            if (topoObjects.get(indexObject).getFpIndex().getCurveHs() != null) {
                CurveZVDto zvDto = ConvertZV.getVFromZ(topoObjects.get(indexObject).getFpIndex().getCurveHs(),
                        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getRz());
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setV(zvDto.getResult());
                ConvertZV.setErrMsgCurveHs(topoObjects.get(indexObject).getFpIndex(), zvDto.getMsg());
            }
        } else {
            // 记录界面传入的蓄滞洪区的参数
            //            record = (DS_ProcessRes) CommonFun.copyOneObject(topoObjects.get(indexObject).getFpIndex()
            //            .getData().get(timeNum));
            // 需要重新调度一遍, 将蓄滞洪区的入流改过来, 原来蓄滞洪区的入流为虚拟节点的入流, 同时计算虚拟节点的参数
            //            dispatchTempData = principleData.getFlowByPrinciple(dispatchTempData, indexObject,
            //            topoObjects, timeNum, timeNumOperate, diversionOrDischarge);
            //            data.get(timeNum) = (DS_ProcessRes) CommonFun.copyOneObject(record);
            // 分解flowWay, 若flowWay = 21, 则对应分后口门为固定宽度，排洪口门为调度规则
            // flowWay=22, 分后口门与排洪口门均为固定宽度
            int x = topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getFlowWay();
            //月亮泡不可以同时排洪或分洪

            //只要改了一个时段, 后面的就都是一样的
            if (dispatchTempData.isFirst()) {
                for (int i = timeNum + 1; i < topoObjects.get(indexObject).getFpIndex().getData().size(); i++) {
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setFlowWay(x);
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setNUsedGates(
                            (Integer[][]) CommonFun.copyOneObject(
                                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()));
                }
                dispatchTempData.setFirst(false);
            }
            // 分解后, flowWays[0]对应排洪口, flowWays[1]对应分洪口
            int[] flowWays = new int[2];
            int num = 0;
            while (x >= 1) {
                flowWays[num] = x % 10;
                x = x / 10;
                num++;
            }
            //            temp = (principleData.getResNode(idComp + "1") != null)?principleData.getResNode(idComp +
            //            "1"):principleData.getResNode(idComp + "V");
            //            double qDalai = (principleData.getResNode(Constants.ID_COMP_DALAI)!=null)?principleData
            //            .getResNode(Constants.ID_COMP_DALAI).resPlans[0].common[timeNum].qIn:principleData
            //            .getResNode(Constants.STATION_CODE_DALAI).resPlans[0].common[timeNum].qIn;
            //            double qTaonan = (principleData.getResNode(Constants.ID_COMP_TAONAN)!=null)?principleData
            //            .getResNode(Constants.ID_COMP_TAONAN).resPlans[0].common[timeNum].qIn:principleData
            //            .getResNode(Constants.STATION_CODE_TAONAN).resPlans[0].common[timeNum].qIn;
            //            if (spillWayType == 1 || spillWayType == 3) {
            if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DIVERSION) {
                double zRiver =
                        MathFun.insert3(topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep(),
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getZqSpillways().stream().mapToDouble(DZqSpillway::getQ).toArray(),
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getZqSpillways().stream().mapToDouble(DZqSpillway::getZ).toArray(),
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getZqSpillways().size());
                if (zRiver > topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1).getRz()) {
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(outFlow.getOutFlow(zRiver,
                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()[0][0],
                            topoObjects.get(indexObject).getFpIndex().getSpillways()));
                } else {
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(0.0);
                }
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote(
                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getShortname() + " " +
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getStatename() + "-" +
                                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()[0][0] +
                                ";");
            }
            if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDsc() == null) {
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(0.0);
            }
            //                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(0.0);
            //            }
            //            if (spillWayType == 2 || spillWayType == 3) {
            if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DISCHARGE) {
                double zRiver =
                        MathFun.insert3(topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep(),
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getZqSpillways().stream().mapToDouble(DZqSpillway::getQ).toArray(),
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getZqSpillways().stream().mapToDouble(DZqSpillway::getZ).toArray(),
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getZqSpillways().size());
                if (zRiver < topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1).getRz()) {
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(outFlow.getOutFlow(
                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum - 1).getRz(),
                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()[0][0],
                            topoObjects.get(indexObject).getFpIndex().getSpillways()));
                } else {
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(0.0);
                }
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote(
                        topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getShortname() + " " +
                                topoObjects.get(indexObject).getFpIndex().getSpillways().get(0).getZqMethods().get(0)
                                        .getStatename() + "-" +
                                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()[0][0] +
                                ";");
            }
            if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDvr() == null) {
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(0.0);
            }
            //                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(0.0);
            //            }
            // 不调洪的情况
            //            if(spillWayType == 0) {
            //                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(0.0);
            //            }
            // 入流合理性校核
            if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQDvr() >
                    topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep()) {
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                        .setQDvr(topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getQPrep());
            }

            // 计算虚拟节点的出流
            //            temp.resPlans[0].common[timeNum].qOut = temp.resPlans[0].common[timeNum].qIn - data.get
            //            (timeNum).qIn + data.get(timeNum).qOut;
            // 洮南站流量汇入
            //            data.get(timeNum).qIn += qTaonan;
            // 水量平衡计算,
            resRoutingOnePeriod(timeNum, topoObjects.get(indexObject));// 内部自动判断出流是否超过
        }
        return dispatchTempData;
    }

    /***
     * 按规划的洪水调度原则进行调洪计算, 单时段
     *            调度规则
     * @param timeNum
     *            时段
     */
    private DispatchTempDataDto makePlanByPrinciple(DispatchTempDataDto dispatchTempData, int indexObject,
                                                    List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                    int timeNum, int timeNumOperate, int diversionOrDischarge) {
        dispatchTempData = principleData
                .getFlowByPrinciple(dispatchTempData, indexObject, topoObjects, timeNum, timeNumOperate,
                        diversionOrDischarge);
        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                .setFlowWay(DispatchConstants.FLOW_WAY_DOUBLE_GATE_BY_RUNGEKUTTA);
        resRoutingOnePeriod(timeNum, topoObjects.get(indexObject));
        //        resNode.resPlans[0].n = this.nPeriods; // 调度后由于checkZSpecial可能使时段数变大
        String mannerNote = "";
        for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
            for (int k = 0; k < topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates(); k++) {
                if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()[j][k] >= 0) {
                    int gateWidth =
                            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates()[j][k];
                    mannerNote = mannerNote +
                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getShortname() + " " +
                            topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getZqMethods().get(k)
                                    .getStatename() + "-" + gateWidth + ";";
                }
            }
        }
        topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote(mannerNote);
        return dispatchTempData;
    }

    /**
     * 根据规则检查调洪参数
     */
    private DispatchTempDataDto checkPlanByPrinciple(DispatchTempDataDto dispatchTempData, int indexObject,
                                                     List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                     int timeNum, int timeNumOperate) {
        dispatchTempData = principleData
                .checkOutFlowWayByPrinciple(dispatchTempData, indexObject, topoObjects, timeNum, timeNumOperate);
        return dispatchTempData;
    }

    /**
     * 根据调洪规则进行每个时段的调洪计算
     */
    public void resRoutingOnePeriod(int timeNum, TopoObjectDto object) {
        object.getFpIndex().getData().get(timeNum)
                .setV(waterBalance(object.getFpIndex().getData().get(timeNum - 1).getV(),
                        object.getFpIndex().getData().get(timeNum).getQIn(),
                        object.getFpIndex().getData().get(timeNum).getQOut(),
                        object.getFpIndex().getData().get(timeNum).getQDvr(),
                        object.getFpIndex().getData().get(timeNum).getQDsc(),
                        CommonFun.multiKFromFlowToVolumn(object.getFpIndex().getClen(), object.getFpIndex().getUnt()),
                        timeNum));
        // 保证库容不为负
        if (object.getFpIndex().getData().get(timeNum).getV() < 0) {
            double qDsc =
                    ((object.getFpIndex().getData().get(timeNum).getQIn() == null) ? 0 : object.getFpIndex().getData()
                            .get(timeNum).getQIn()) +
                            ((object.getFpIndex().getData().get(timeNum).getQDvr() == null) ? 0 : object.getFpIndex()
                                    .getData().get(timeNum).getQDvr()) -
                            ((object.getFpIndex().getData().get(timeNum).getQOut() == null) ? 0 : object.getFpIndex()
                                    .getData().get(timeNum).getQOut()) +
                            (object.getFpIndex().getData().get(timeNum - 1).getV()) / CommonFun
                                    .multiKFromFlowToVolumn(object.getFpIndex().getClen(),
                                            object.getFpIndex().getUnt());
            object.getFpIndex().getData().get(timeNum).setQDsc(qDsc);
            if (object.getFpIndex().getData().get(timeNum).getQDsc() < 0) {
                object.getFpIndex().getData().get(timeNum).setQDsc(0.0);
            }
        }
        object.getFpIndex().getData().get(timeNum)
                .setV(waterBalance(object.getFpIndex().getData().get(timeNum - 1).getV(),
                        object.getFpIndex().getData().get(timeNum).getQIn(),
                        object.getFpIndex().getData().get(timeNum).getQOut(),
                        object.getFpIndex().getData().get(timeNum).getQDvr(),
                        object.getFpIndex().getData().get(timeNum).getQDsc(),
                        CommonFun.multiKFromFlowToVolumn(object.getFpIndex().getClen(), object.getFpIndex().getUnt()),
                        timeNum));
        if (object.getFpIndex().getCurveHs() != null) {
            CurveZVDto zvDto = ConvertZV
                    .getZFromV(object.getFpIndex().getCurveHs(), object.getFpIndex().getData().get(timeNum).getV());
            object.getFpIndex().getData().get(timeNum).setRz(zvDto.getResult());
            ConvertZV.setErrMsgCurveHs(object.getFpIndex(), zvDto.getMsg());
        }
        if (object.getFpIndex().getData().get(timeNum).getRz() <= 0) {
            object.getFpIndex().getData().get(timeNum).setRz(0.0);
            object.getFpIndex().getData().get(timeNum).setV(0.0);
        }
    }

    private double waterBalance(Double vBeg, Double qIn, Double qOut, Double qDvr, Double qDsc, Double lSnds,
                                int iStep) { // 水量平衡法
        double vEnd;
        vEnd = vBeg + ((qIn != null ? qIn : 0) + (qDvr != null ? qDvr : 0) - (qOut != null ? qOut : 0) -
                (qDsc != null ? qDsc : 0)) * lSnds;
        return vEnd;
    }
}
